home *** CD-ROM | disk | FTP | other *** search
- /* nlist for mintlib/toslib.
- * Written by S.N. Henson and released into the public domain.
- *
- * Currently uses just standard and GST extended symbol formats.
- */
-
- #include <st-out.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include <macros.h>
- #include <nlist.h>
- #include <string.h>
-
- #define SYM_BUFSIZE 100
- #define SYMSIZE sizeof(struct asym)
- #define GSYM_SIZE 23
-
- static int sym_fd;
-
- static long symcount;
-
- static int getsym __PROTO((struct asym *sptr));
-
- /* Read a symbol from a file and put it in sptr */
- static int getsym(sptr)
- struct asym *sptr;
- {
- static struct asym symbuf[SYM_BUFSIZE],*symptr;
- static long symread;
- if( !symread )
- {
- symread=min(sizeof(symbuf),symcount);
- if((int)symread != read(sym_fd,symbuf, (int)symread))
- {
- close(sym_fd);
- symread=0;
- errno=EREAD; /* Premature EOF */
- return -1;
- }
- symptr=symbuf;
- }
-
- *sptr=*symptr++;
- symread-=SYMSIZE;
-
- if( symread < 0 )
- {
- symread=0;
- errno=EREAD;
- return -1;
- }
-
- return 0;
- }
-
- int nlist(file,nl)
- char *file;
- struct nlist *nl;
- {
-
- struct nlist *p;
-
- struct aexec hbuf;
-
- struct asym sym;
-
- long nl_count;
-
- if(!file || !nl)
- {
- errno=EFAULT;
- return -1;
- }
-
- if( ( sym_fd=open(file,O_RDONLY) ) == -1 ) return -1;
-
- /* Read in file header */
- read(sym_fd,&hbuf,(int) sizeof(hbuf));
-
- /* Executable file ? */
- if(A_BADMAG(hbuf))
- {
- close(sym_fd);
- errno=ENOEXEC;
- return -1;
- }
-
- /* Any symbols? */
- if((symcount=hbuf.a_syms) == 0)
- {
- errno=EDOM;
- return -1;
- }
-
- if( symcount < sizeof(struct asym) )
- {
- close(sym_fd);
- errno=EREAD;
- return -1;
- }
-
- /* Seek to symbol table */
- if( A_SYMOFF(hbuf)!=lseek(sym_fd,A_SYMOFF(hbuf),SEEK_SET) )
- {
- close(sym_fd);
- errno=EREAD;
- return -1;
- }
-
- /* Count number of symbols to match */
- for(p=nl,nl_count=0;p->n_name;p++)
- {
- nl_count++;
- p->n_value=p->n_type=0;
- }
-
- if(!nl_count) return 0;
-
- do
- {
- char name[GSYM_SIZE];
-
- /* Get one symbol from file */
- if(getsym(&sym)) return -1;
-
- symcount-=SYMSIZE;
-
- strncpy(name,sym.a_name,8);
-
- /* If extended symbol, get rest of name */
- if( (sym.a_type & A_LNAM) == A_LNAM)
- {
- if( (symcount <= 0) || getsym((struct asym *)(name+8)))
- return -1;
- symcount-=SYMSIZE;
- name[22]=0;
- }
- else name[8]=0;
-
- /* Check for match */
- for(p=nl;p->n_name;p++)
- {
- if(p->n_type || strcmp(name,p->n_name)) continue;
- p->n_value=sym.a_value;
- p->n_type=sym.a_type;
- if(--nl_count==0) return 0;
- }
- }
- while(symcount > 0);
-
- return (int)nl_count;
- }
-